from typing import List, Optional

from langchain_classic.agents import AgentExecutor, create_tool_calling_agent
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_ollama import ChatOllama

from Tools.voice_management_tool import add_voiceprint, delete_voiceprint, set_global_instances
from Tools.websocket_tool import (set_websocket_server, open_browser, send_message_to_frontend,
                                  get_connected_clients_count)

# 系统提示语
SYSTEM_PROMPT = """
你是桌面宠物智能助手，名叫小飞（用户语音识别的小飞可能是类似音，无需在意，默认是你就行）。
同时也是一个直接的语音交互系统，无需唤醒词，当用户说话时，你会自动响应。

你可以：
1. 打开浏览器
2. 向前端发送消息
3. 查询当前连接的客户端数量
4. 添加声纹特征（会弹出图形界面让用户输入信息和录制音频）
5. 删除指定用户的声纹特征（会弹出图形界面让用户输入要删除的用户名）

在与用户交互时，请根据用户的需求选择合适的工具来完成任务。

重要提醒：
- 当用户要求添加声纹时，直接调用add_voiceprint工具，不需要用户提供额外信息，工具会弹出图形界面让用户输入
- 当用户要求删除声纹时，直接调用delete_voiceprint工具，不需要用户提供用户名，工具会弹出图形界面让用户输入
- 已认证用户可以直接执行这些操作，无需输入密码；只有游客需要输入管理员密码

请以友好和专业的语气回复用户，同时回复要简单明了。
纯文本回复，不要表情包。
请携带用户的身份给回，我会给身份给你的。
"""

def create_websocket_tools(websocket_server):
    """
    创建WebSocket工具实例
    
    Args:
        websocket_server: WebSocket服务器实例
        
    Returns:
        list: 工具列表
    """
    # 设置 WebSocket 服务器实例供工具函数使用
    set_websocket_server(websocket_server)
    set_global_instances(websocket_server=websocket_server)
    
    # 返回带有 @tool 装饰器的函数列表（移除了perform_voiceprint_verification）
    return [open_browser, send_message_to_frontend, get_connected_clients_count, add_voiceprint, delete_voiceprint]

def get_llm_response(prompt: str, tools: Optional[List] = None) -> str:
    """
    调用大语言模型获取响应
    
    Args:
        prompt: 用户输入的提示语
        tools: 可选的工具列表
        
    Returns:
        str: 模型的响应
    """
    # 配置Ollama模型
    llm = ChatOllama(
        base_url="http://10.108.13.254:11434",
        model="glm-4.6:cloud"
    )
    
    # 如果提供了工具，则创建带有工具调用能力的Agent
    if tools:
        # 创建提示模板
        prompt_template = ChatPromptTemplate.from_messages([
            ("system", SYSTEM_PROMPT),
            ("human", "{input}"),
            MessagesPlaceholder(variable_name="agent_scratchpad")
        ])
        
        # 创建Agent
        agent = create_tool_calling_agent(llm, tools, prompt_template)
        
        # 创建Agent执行器
        agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
        
        # 执行Agent并获取结果
        print("🔍 开始调用Agent...")
        try:
            response = agent_executor.invoke({"input": prompt})
            print("✅ Agent调用完成，准备返回结果...")
            return response["output"]
        except Exception as e:
            error_msg = f"❌ Agent调用失败：{str(e)}"
            print(error_msg)
            return error_msg
    
    # 如果没有提供工具，则直接调用模型
    response = llm.invoke(prompt)
    return response.content